home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / us20src.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1992-06-26  |  8KB  |  387 lines

  1. /*    MAIN:    Main module for MicroSPELL 2.0
  2.         Spell Checker and Corrector
  3.  
  4.         (C)opyright May 1987,1992 by Daniel Lawrence
  5.         All Rights Reserved
  6.  
  7.     Revision History:
  8.  
  9.     21-jul-87
  10.     [Released version 1.0 to the USENET]
  11.     01-jan-91
  12.     - write BIC program to make spelling suggestions
  13.     11-oct-91
  14.     - fixed major bug in BIC increasing speed greatly
  15.     20-oct-91
  16.     - added letter index to begining of compressed dictionary
  17.     - eliminated code for non-compressed dictionary
  18.     - added code to scan.cmd to use BIC to suggest corrections
  19.     22-oct-91
  20.     - merged upper and lower case dictionaries
  21.     25-oct-91
  22.     - added -h switch to suppress header
  23.     26-jun-92
  24.     [Released version 2.0 to BBS/USENET]
  25. */
  26.  
  27. #define    maindef    1
  28.  
  29. #include    <stdio.h>
  30. #include    "dopt.h"
  31. #include    "dstruct.h"
  32. #include    "ddef.h"
  33.  
  34. int swheader = TRUE;
  35.  
  36. main(argc, argv)
  37.  
  38. int argc;    /* command line argument count */
  39. char **argv;    /*              argument vector */
  40.  
  41. {
  42.     register WORD *tword;
  43.  
  44.     /* check to see if they need help.... */
  45.     if (argc == 1) {
  46.         usage();
  47.         exit(EXBADOPT);
  48.     }
  49.  
  50.     /* initialize number of words to filter from input */
  51.     numfiltr = 0;
  52.  
  53.     /* parse the command line */
  54.     while (--argc) {
  55.         argv++;        /* skip to next argument */
  56.         if (argv[0][0] == '-')
  57.             option(&argc, &argv);
  58.         else
  59.             sfile(argv[0]);
  60.     }
  61.  
  62.     /* announce us */
  63.     if (swheader)
  64.         printf("MicroSPELL %s    Interactive Speller and Corrector\n", VERSION);
  65.  
  66.     /* init the lower case table */
  67.     init_lcase();
  68.  
  69.     /* load the common word list */
  70.     loadcom();
  71.  
  72.     /* prepare to spell */
  73.     comsort();
  74.     if (swdebug && (numfiltr > numcom))
  75.         printf("[%u User words loaded and sorted]\n", numfiltr - numcom);
  76.  
  77.     if (mopen() == FALSE)
  78.         exit(EXMDICT);
  79.     mclose();
  80.  
  81.     if ((outfile = fopen("spell.lst", "w")) == NULL) {
  82.         printf("%%Can not open temp file\n");
  83.         exit(EXTEMP);
  84.     }
  85.  
  86.     /* read the words in */
  87.     tword = getword();
  88.     while (tword) {
  89.         ++totwords;
  90.         if (!iscom(tword->w_text)) {
  91.             ++prowords;
  92.             insword(tword);
  93.         }
  94.         tword = getword();
  95.     }
  96.  
  97.     /* if there are words left to spell check... go do it */
  98.     if (numwords > 0)
  99.         check();
  100.     if (swwords)
  101.         fprintf(outfile, "!end\n");
  102.     else
  103.         fprintf(outfile, "-2\n0\n");
  104.     fclose(outfile);
  105.  
  106.     printf("[%u/%u words processed]\n", prowords, totwords);
  107.  
  108.     if (swemacs) {
  109.         perform("emacs @scan.cmd");
  110. #if    ATARI & LATTICE
  111.         printf("%%Cannot execute EMACS from here...type\m");
  112.         printf("     emacs @scan.cmd\nto scan document\n");
  113. #endif
  114.     }
  115.  
  116.     exit(EXGOOD);
  117. }
  118.  
  119. insword(cword)    /* insert a word in the source word list */
  120.  
  121. WORD *cword;
  122.  
  123. {
  124.     register WORD *wp;    /* temporary word pointer */
  125.  
  126.     if (numwords == MAXWORDS)
  127.         check();
  128.  
  129.     /* malloc room for the word */
  130.     wp = NULL;
  131.     while (wp == NULL && numwords >= 0) {
  132.         wp = (WORD *)malloc(sizeof(WORD) + strlen(cword->w_text) + 1);
  133.         if (wp == NULL)
  134.             check();
  135.     }
  136.  
  137.     if (wp == NULL) {
  138.         printf("%%Out of Memory while scanning input file\n");
  139.         exit(EXNORAM);
  140.     }
  141.  
  142.     /* copy the word in */
  143.     wp->w_file = cword->w_file;
  144.     wp->w_line = cword->w_line;
  145.     wp->w_col = cword->w_col;
  146.     strcpy(wp->w_text, cword->w_text);
  147.  
  148.     /* and hook it in */
  149.     sword[numwords++] = wp;
  150. }
  151.  
  152. option(argc, argv)    /* process a command line option */
  153.  
  154. int *argc;        /* ptr to cmd line argc */
  155. char ***argv;        /* paramters */
  156.  
  157. {
  158.     register char ochar;    /* option character */
  159.  
  160.     ochar = (*argv)[0][1];
  161.     switch (ochar) {
  162.         case 'd':    /* debug switched on */
  163.             swdebug = TRUE;
  164.             break;
  165.  
  166.         case 'h':    /* suppress the header */
  167.             swheader = FALSE;
  168.             break;
  169.  
  170.         case 'e':    /* emacs to be used to correct */
  171.             swemacs = TRUE;
  172.             break;
  173.  
  174.         case 'u':    /* specify user dictionary */
  175.             if ((*argv)[0][2])
  176.                 uread(&(*argv)[0][2]);
  177.             else {
  178.                 if (*argc > 0)
  179.                     uread((*argv)[1]);
  180.                     (*argv)++;
  181.                     (*argc)--;
  182.                 }
  183.             break;
  184.  
  185.         case 'w':    /* output a word list instead of locations */
  186.             swwords = TRUE;
  187.             break;
  188.  
  189.         default:    /* bad option */
  190.             printf("%%No such option '%s'\n", &(*argv)[0][1]);
  191.             exit(EXBADOPT);
  192.     }
  193. }
  194.  
  195. sfile(fname)    /* record and check the file to be spelled */
  196.  
  197. char *fname;    /* file to spell */
  198.  
  199. {
  200.     if (swdebug)
  201.         printf("[Queueing '%s' to spell]\n", fname);
  202.  
  203.     /* check to see if we have too many */
  204.     if (numspell >= MAXSPELL) {
  205.         printf("%%Too many input files... '%s' ignored\n", fname);
  206.         return(FALSE);
  207.     } else {
  208.         strcpy(splname[numspell++], fname);
  209.         return(TRUE);
  210.     }
  211. }
  212.  
  213. usage()        /* print the command line usage */
  214.  
  215. {
  216.     printf("MicroSPELL %s    Interactive Speller and Corrector\n", VERSION);
  217.     puts("\nUsage\n");
  218.     puts("    spell {<options>} <file> {<file>.....<file>}\n");
  219.     puts("Options:\n");
  220.     puts("    -d        Debugging mode");
  221.     puts("    -e        Use MicroEMACS to scan errors");
  222.     puts("    -u<fname>    Use user word list <fname>");
  223.     puts("    -w        Output a word list instead of location list");
  224. }
  225.  
  226. #if    RAMSIZE & LATTICE & MSDOS
  227. /*    These routines will allow me to track memory usage by placing
  228.     a layer on top of the standard system malloc() and free() calls.
  229.     with this code defined, the number of allocated bytes is displayed
  230.     in the upper right corner of the screen
  231. */
  232.  
  233. #undef    malloc
  234. #undef    free
  235.  
  236. char *allocate(nbytes)    /* allocate nbytes and track */
  237.  
  238. unsigned nbytes;    /* # of bytes to allocate */
  239.  
  240. {
  241.     char *mp;    /* ptr returned from malloc */
  242.     char *malloc();
  243.  
  244.     mp = malloc(nbytes);
  245.     if (mp) {
  246.         envram += nbytes;
  247. #if    RAMSHOW
  248.         dspram();
  249. #endif
  250.     }
  251.  
  252.     return(mp);
  253. }
  254.  
  255. release(mp)    /* release malloced memory and track */
  256.  
  257. char *mp;    /* chunk of RAM to release */
  258.  
  259. {
  260.     unsigned *lp;    /* ptr to the long containing the block size */
  261.  
  262.     if (mp) {
  263.         lp = ((unsigned *)mp) - 1;
  264.  
  265.         /* update amount of ram currently malloced */
  266.         envram -= (long)*lp - 2;
  267.         free(mp);
  268. #if    RAMSHOW
  269.         dspram();
  270. #endif
  271.     }
  272. }
  273.  
  274. #if    RAMSHOW
  275. dspram()    /* display the amount of RAM currently malloced */
  276.  
  277. {
  278.     char mbuf[20];
  279.     char *sp;
  280.  
  281. /*    TTmove(term.t_nrow - 1, 70);*/
  282.     sprintf(mbuf, "[%lu]", envram);
  283.     sp = &mbuf[0];
  284.     puts(sp);
  285. }
  286. #endif
  287. #endif
  288.  
  289. #if    AZTEC & MSDOS
  290. #undef    fgetc
  291. #undef    fgets
  292. /*    a1gets:        Get an ascii string from a file using a1getc    */
  293.  
  294. char *a1gets(buffer, length, fp)
  295.  
  296. char *buffer;    /* buffer to leave string in */
  297. int length;    /* maximum length of string */
  298. FILE *fp;    /* file to get string from */
  299.  
  300. {
  301.     register int c;        /* current character read */
  302.     register char *bp;    /* pointer into buffer */
  303.  
  304.     bp = buffer;
  305.  
  306.     while ((c = a1getc(fp))    != EOF) {
  307.         *bp++ = (char)c;
  308.         if (c == '\n')
  309.             break;
  310.     }
  311.  
  312.     *bp = 0;
  313.     if (c == EOF)
  314.         return(NULL);
  315.     else
  316.         return(buffer);
  317. }
  318.  
  319. /*    a1getc:        Get an ascii char from the file input stream
  320.             but DO NOT strip the high bit
  321. */
  322.  
  323. int a1getc(fp)
  324.  
  325. FILE *fp;
  326.  
  327. {
  328.     int c;        /* translated character */
  329.  
  330.     c = getc(fp);    /* get the character */
  331.  
  332.     /* if its a <LF> char, throw it out  */
  333.     while (c == 10)
  334.         c = getc(fp);
  335.  
  336.     /* if its a <RETURN> char, change it to a LF */
  337.     if (c == '\r')
  338.         c = '\n';
  339.  
  340.     /* if its a ^Z, its an EOF */
  341.     if (c == 26)
  342.         c = EOF;
  343.  
  344.     return(c);
  345. }
  346. #endif
  347.  
  348. perform(cmd)    /* send out a DOS command and execute it */
  349.  
  350. char *cmd;    /* command to execute */
  351.  
  352. {
  353.     if (swdebug)    /* output command string with diagnostics */
  354.         puts(cmd);
  355.  
  356. #if    LATTICE & ~ATARI & ~CMS
  357.     forkl(getenv("COMSPEC"),"command","-C",cmd,NULL);
  358.     return(wait());
  359. #endif
  360.  
  361. #if    (AZTEC & ~AMIGA) | CMS | TURBO
  362.     system(cmd);
  363.     return(TRUE);
  364. #endif
  365.  
  366. #if    AZTEC & AMIGA
  367.     Execute(cmd, 0L, 0L);
  368.     return(TRUE);
  369. #endif
  370. }
  371.  
  372. #if    CMS
  373. #undef    fopen
  374. /*    The IBM 30xx likes to tell us when file opens
  375.     fail...it's too chatty....I like to handle these myself    */
  376.  
  377. FILE *cmsopen(file, mode)
  378.  
  379. char *file;    /* name of file to open */
  380. char *mode;    /* mode to open it in */
  381.  
  382. {
  383.     quiet(1);
  384.     return(fopen(file,mode));
  385. }
  386. #endif
  387.